﻿// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "miHoYo/Character/Avatar_Emission" {
	Properties {
		_MainColor ("Main Color", Color) = (1, 1, 1, 1)

		_Scale ("Scale Compared to Maya", Float) = 0.01
		_BloomFactor ("Bloom Factor", float) = 1
		
		//Texture
		_MainTex ("Main Tex (RGB)", 2D) = "white" {}
		_LightMapTex ("Light Map Tex (RGB)", 2D) = "gray" {}

		//Light
		_LightSpecColor ("Light Specular Color", Color) = (1, 1, 1, 1)

		//Shadow
		[HideInInspector]_LightArea ("Light Area Threshold", Range(0, 1)) = 0.51
		[HideInInspector]_SecondShadow ("Second Shadow Threshold", Range(0, 1)) = 0.51
		_FirstShadowMultColor ("First Shadow Multiply Color", Color) = (0.9, 0.7, 0.75, 1)
		_SecondShadowMultColor ("Second Shadow Multiply Color", Color) = (0.75, 0.6, 0.65, 1)

		//Specular
		_Shininess ("Specular Shininess", Range(0, 100)) = 10
		_SpecMulti ("Specular Multiply Factor", Range(0, 1)) = 0.1

		//Emission
		_Emission ("Emission", Range(1, 100)) = 1
		_EmissionBloomFactor ("Emission Bloom Factor", Float) = 1

		//Outline
		_OutlineWidth ("Outline Width", Range(0, 100)) = 0.2
		_OutlineColor ("Outline Color", Color) = (0, 0, 0, 1)
		_MaxOutlineZOffset ("Max Outline Z Offset", Range(0, 100)) = 1
		_OutlineCamStart ("Outline Camera Adjustment Start Distance", Range(0, 10000)) = 1000

		//Camera Fade
		_FadeDistance ("Fade Start Distance", Range(0.1, 10)) = 0.5
		_FadeOffset ("Fade Start Offset", Range(0, 10)) = 1
	}

	SubShader {
		Tags
		 { 
		 	"Queue"="Geometry"
			"RenderType"="Opaque"
			"IgnoreProjector"="True"
			"Reflected"="Reflected"
		 }
		LOD 200
		
		//Base Pass
		
		//Complex Pass
		Pass
		{
			Tags { "LightMode"="ForwardBase" }

			Name "COMPLEX"
			Cull Back

			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag

			#include "UnityCG.cginc"
			#include "../Common/Common_Util.cginc"  
			#include "Character_Common.cginc"

			half _Emission;
			half _EmissionBloomFactor;

			half _FadeDistance;
			half _FadeOffset;

			struct appdata
			{
				float4 vertex : POSITION;
			    float4 normal : NORMAL;
			    float4 texcoord : TEXCOORD0;
			    fixed4 color : COLOR;
			};

			struct v2f {
				float4 position : POSITION;
				fixed4 color : COLOR0;
				half2 texcoord : TEXCOORD0;
				half3 normal : TEXCOORD1;
				float3 objPos : TEXCOORD2;

				fixed diff : COLOR1;
			};

			v2f vert (appdata inData) 
			{
				v2f outData = (v2f)0;

				outData.position = UnityObjectToClipPos(inData.vertex);
				outData.color = inData.color;
				float4 objPos = mul(unity_ObjectToWorld, inData.vertex); 
				outData.objPos = objPos.xyz / objPos.w;
				outData.texcoord = inData.texcoord.xy;

				//Normal
				// 1. cannot get inverse transport of model matrix, just use _Object2World instead
				// there is no problem as long as no scale involved
				// 2. somehow the w component not be zero, so only use xyz
				outData.normal = normalize(mul((float3x3)unity_ObjectToWorld, inData.normal.xyz).xyz);

				//Diffuse
				// calculate diffuse factor
				outData.diff = diffuse_factor(outData.normal, _WorldSpaceLightPos0.xyz);
				
				return outData;
			} // End of vert

			half4 frag (v2f inData) : COLOR
			{
				half4 outColor = (float4)0;
	
				// R: specular intensity
				// G: shadow threshold
				// B: specular shininess 
				fixed3 tex_Light_Color = tex2D(_LightMapTex, inData.texcoord).rgb; 
				
				fixed3 specColor = float3(0.0f, 0.0f, 0.0f).rgb;

				//Diffuse
				fixed4 baseTexColor = tex2D(_MainTex, inData.texcoord);
				fixed3 diffColor = complex_toon_diffuse(inData.diff, inData.color.r, tex_Light_Color.g, baseTexColor.rgb);
				// emission
				diffColor = lerp(diffColor, baseTexColor.rgb * _Emission, baseTexColor.a);
				
				//Specular
				// light dir
				fixed3 N = normalize(inData.normal);

				// pass camera pos
				fixed3 V = normalize(_WorldSpaceCameraPos.xyz - inData.objPos);
				
				fixed3 H = normalize(_WorldSpaceLightPos0 + V);
				fixed t = 1.0f - tex_Light_Color.b;
				fixed s = specular_factor(N, H, _Shininess);

				if (s > t ) // Front Specular
				{
					specColor = _LightSpecColor.rgb * _SpecMulti * tex_Light_Color.r;
				}

				//Final Color
				outColor.rgb = diffColor.rgb * _MainColor.rgb + specColor;
				outColor.rgb *= _LightColor0.rgb;

				outColor.a = lerp(_BloomFactor, _EmissionBloomFactor, baseTexColor.a);

				return outColor;
			} // End of frag
			ENDCG
		} // End of Complex Pass

		//Complex Outline Pass
		// 1. tangent as normal
		// 2. controled by vertex color 
		// 3. without camera near fade
		Pass
		{
			Tags { "LightMode" = "ForwardBase" }

			Name "COMPLEX"
			Cull Front
			ZWrite On 

			CGPROGRAM
			#include "../Common/Common_Outline.cginc" 
			#pragma vertex vert_complex 
			#pragma fragment frag
			ENDCG
		} // End of Complex Outline Pass

	} 
}
